package org.jay.angla.fragment;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import org.achartengine.GraphicalView;
import org.jay.angla.activity.MainActivity_;
import org.jay.angla.activity.WSSettingActivity_;
import org.jay.angla.base.WavelengthScanningRecord;
import org.jay.angla.chart.WSChart;
import org.jay.angla.dialog.BaselineDialog;
import org.jay.angla.dialog.RecordNameDialog;
import org.jay.angla.onlab.OnlabApplication;
import org.jay.angla.onlab.R;
import org.jay.angla.utils.SharePreferenceUtil;
import org.jay.angla.utils.ToastShow;
import org.jay.angla.utils.Utils;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Fragment;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.FrameLayout;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.AdapterView.OnItemLongClickListener;

@SuppressLint("NewApi")
public class FragmentWavelengthScanning extends Fragment implements
		View.OnClickListener {

	private FragmentCallbackListener mListener;
	private FrameLayout mWSLayout;
	private WSChart mChart;
	private GraphicalView mChartView;

	private TextView mIntervalTextView;
	private TextView mTestModeTextView;

	private Button mStartButton;
	private Button mStopButton;
	private Button mRezeroButton;
	private Button mSystemBaselineButton;

	private ListView mListView;
	private SimpleAdapter mAdapter;
	private List<HashMap<String, String>> mData;

	private float mInterval = 0.2f;
	private RecordNameDialog mDialog;

	private Intent mIntent;
	private int mRequestCode;

	private ToastShow mToastShow;

	private BaselineDialog mBaselineDialog;

	private boolean loadHistory = false;
	private int historyId;

	private boolean isRezeroed = false;
	private boolean isRezeroing = false;

	private CheckBox mSmoothBox;
	private int lineIndex = 0;

	@Override
	public void onAttach(Activity activity) {
		// TODO Auto-generated method stub
		mListener = (FragmentCallbackListener) activity;
		super.onAttach(activity);
	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		View rootView = inflater.inflate(R.layout.fragment_wavelength_scanning,
				container, false);
		mWSLayout = (FrameLayout) rootView.findViewById(R.id.chart_ws);
		mChart = new WSChart(getActivity());
		mChartView = mChart.getChartView(getActivity());
		mWSLayout.removeAllViews();
		mWSLayout.addView(mChartView);

		mIntervalTextView = (TextView) rootView
				.findViewById(R.id.tv_wavelength_interval);
		mTestModeTextView = (TextView) rootView.findViewById(R.id.tv_test_mode);

		mStartButton = (Button) rootView.findViewById(R.id.btn_start_test);
		mStopButton = (Button) rootView.findViewById(R.id.btn_stop_test);
		mRezeroButton = (Button) rootView.findViewById(R.id.btn_rezero_test);
		mSystemBaselineButton = (Button) rootView
				.findViewById(R.id.btn_system_baseline);
		mStartButton.setOnClickListener(this);
		mStopButton.setOnClickListener(this);
		mRezeroButton.setOnClickListener(this);
		mSystemBaselineButton.setOnClickListener(this);

		mListView = (ListView) rootView.findViewById(R.id.lv_ws);
		mData = new ArrayList<HashMap<String, String>>();
		mAdapter = new SimpleAdapter(getActivity(), mData,
				R.layout.item_sw_test, new String[] { "id", "wavelength",
						"abs", "trans", "energy" }, new int[] {
						R.id.item_number, R.id.item_wavelength, R.id.item_abs,
						R.id.item_trans, R.id.item_energy });
		mListView.setAdapter(mAdapter);
		mBaselineDialog = new BaselineDialog(getActivity());
		mBaselineDialog.setOnClickListener(this);
		mDialog = new RecordNameDialog(getActivity());
		mDialog.setOnClickListener(this);
		loadSp();
		if (loadHistory) {
			List<String> namesList = OnlabApplication.getInstance()
					.getWavelengthScanningDB().getTables();
			// load select record
			String recordname = namesList.get(historyId);
			List<WavelengthScanningRecord> list = OnlabApplication
					.getInstance().getWavelengthScanningDB()
					.getRecords(recordname);
			clearData();
			for (int i = 0; i < list.size(); i++) {
				WavelengthScanningRecord record = list.get(i);
				addOneTestItem(record);
				float yValue = 0.00f;
				if (OnlabApplication.getInstance().getSpUtil().getTestMode() == WSSettingActivity_.TEST_MODE_ABS) {
					yValue = record.getAbs();
				} else if (OnlabApplication.getInstance().getSpUtil()
						.getTestMode() == WSSettingActivity_.TEST_MODE_TRANS) {
					yValue = record.getTrans() * 100;
				} else {
					yValue = record.getEnergy();
				}
				// TODO??
				// mChart.add(lineIndex, record.getWavelength(), yValue);
				// lineIndex = lineIndex + 1;
			}
			mChartView.postInvalidate();
		}

		mIntent = new Intent();
		mIntent.setClass(getActivity(), WSSettingActivity_.class);
		mToastShow = new ToastShow(getActivity());
		if (!loadHistory) {
			mRequestCode = 0;
			startActivityForResult(mIntent, mRequestCode);
		}

		mSmoothBox = (CheckBox) rootView.findViewById(R.id.cb_smooth);
		mSmoothBox.setOnCheckedChangeListener(new OnCheckedChangeListener() {

			@Override
			public void onCheckedChanged(CompoundButton arg0, boolean arg1) {
				// TODO Auto-generated method stub
				if (arg1) {
					mToastShow.toastShow("checked");
				} else {
					mToastShow.toastShow("unchecked");
				}
			}
		});
		beforeTest();
		return rootView;
	}

	private void beforeTest() {
		mStartButton.setEnabled(true);
		mStopButton.setEnabled(false);
		isRezeroed = false;
		isRezeroing = false;
	}

	public void rezeroFinish() {
		isRezeroed = true;
		isRezeroing = false;
		mStartButton.setEnabled(true);
		mStopButton.setEnabled(true);
	}

	@Override
	public void onDestroyView() {
		// TODO Auto-generated method stub
		super.onDestroyView();
		((MainActivity_) getActivity()).setMainButtonsEnable();
		loadHistory = false;
	}

	public void loadHistoryById(int id) {
		loadHistory = true;
		historyId = id;
		if (isAdded()) {
			List<String> namesList = OnlabApplication.getInstance()
					.getWavelengthScanningDB().getTables();
			// load select record
			String recordname = namesList.get(historyId);
			List<WavelengthScanningRecord> list = OnlabApplication
					.getInstance().getWavelengthScanningDB()
					.getRecords(recordname);
			clearData();
			for (int i = 0; i < list.size(); i++) {
				WavelengthScanningRecord record = list.get(i);
				addOneTestItem(record);
				float yValue = 0.00f;
				if (OnlabApplication.getInstance().getSpUtil().getTestMode() == WSSettingActivity_.TEST_MODE_ABS) {
					yValue = record.getAbs();
				} else if (OnlabApplication.getInstance().getSpUtil()
						.getTestMode() == WSSettingActivity_.TEST_MODE_TRANS) {
					yValue = record.getTrans() * 100;
				} else {
					yValue = record.getEnergy();
				}
				// TODO:???
				// mChart.add(record.getWavelength(), yValue);
			}
			mChartView.postInvalidate();
		}
	}

	private void clearData() {
		mData.clear();
		mAdapter.notifyDataSetChanged();
	}

	@Override
	public void onActivityResult(int requestCode, int resultCode, Intent data) {
		// TODO Auto-generated method stub
		// super.onActivityResult(requestCode, resultCode, data);
		loadSp();
	}

	private void loadSp() {
		SharePreferenceUtil sp = OnlabApplication.getInstance().getSpUtil();
		float uplimit = sp.getWSUpLimit();
		float downlimit = sp.getWSDownLimit();
		float interval = sp.getWSInterval();
		float startWavelength = sp.getWSStartWl();
		float endWavelength = sp.getWSEndWl();
		int testMode = sp.getWSTestMode();
		prepareForUI(uplimit, downlimit, interval, startWavelength,
				endWavelength, testMode);
	}

	private void prepareForUI(float uplimit, float downlimit, float interval,
			float startWavelength, float endWavelength, int testMode) {
		mIntervalTextView.setText(getString(R.string.interval_string)
				+ interval + " nm");
		mInterval = interval;

		mChart.clear2();

		String testModeString = getString(R.string.mode_string);
		if (testMode == WSSettingActivity_.TEST_MODE_ABS) {
			testModeString += getString(R.string.abs_string);
			mChart.setAbsTitle();
			// TODO:??
			// if (mData.size() > 0) {
			// mChart.clear();
			// for (int i = 0; i < mData.size(); i++) {
			// mChart.add(
			// Float.parseFloat(mData.get(i).get("wavelength")),
			// Float.parseFloat(mData.get(i).get("abs")));
			// }
			// mChartView.postInvalidate();
			// }

		} else if (testMode == WSSettingActivity_.TEST_MODE_TRANS) {
			testModeString += getString(R.string.trans_string);
			mChart.setTransTitle();
			// TODO:???
			// if (mData.size() > 0) {
			// mChart.clear();
			// for (int i = 0; i < mData.size(); i++) {
			// mChart.add(
			// Float.parseFloat(mData.get(i).get("wavelength")),
			// Float.parseFloat(mData.get(i).get("trans")) * 100);
			// }
			// mChartView.postInvalidate();
			// }
		} else if (testMode == WSSettingActivity_.TEST_MODE_ENERGY) {
			testModeString += getString(R.string.energy_string);
			mChart.setEnergyTitle();
			// TODO:??
			// if (mData.size() > 0) {
			// mChart.clear();
			// for (int i = 0; i < mData.size(); i++) {
			// mChart.add(
			// Float.parseFloat(mData.get(i).get("wavelength")),
			// Float.parseFloat(mData.get(i).get("energy")));
			// }
			// mChartView.postInvalidate();
			// }
		}
		mTestModeTextView.setText(testModeString);
		mChart.setXLimit(startWavelength, endWavelength);
		mChart.setYLimit(downlimit, uplimit);
		mChartView.postInvalidate();
	}

	private void addOneTestItem(WavelengthScanningRecord record) {
		HashMap<String, String> item = new HashMap<String, String>();
		item.put("id", "" + (mData.size() + 1));
		item.put("wavelength", "" + record.getWavelength());
		if (OnlabApplication.getInstance().getSpUtil().isLowAccuracy()) {
			item.put("abs", String.format("%.3f", record.getAbs()));
			item.put("trans", String.format("%.1f", record.getTrans() * 100));
		} else {
			item.put("abs", String.format("%.4f", record.getAbs()));
			item.put("trans", String.format("%.2f", record.getTrans() * 100));
		}
		item.put("energy", "" + record.getEnergy());
		item.put("date", "" + record.getDate());
		mData.add(item);
		mAdapter.notifyDataSetChanged();
		if (mData.size() > 0) {
			mListView.setSelection(mData.size() - 1);
		}
	}

	public void setting() {
		mIntent.setClass(getActivity(), WSSettingActivity_.class);
		mToastShow = new ToastShow(getActivity());
		mRequestCode = 0;
		startActivityForResult(mIntent, mRequestCode);
	}

	public void save() {
		String name = getString(R.string.wavelength_scanning_exp_string);
		SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
		name += format.format(new Date());
		mDialog.show();
		mDialog.setEditText(name);
	}

	public void updateBaseline(float wavelength, int a, int energy) {
		mBaselineDialog.addOneItem(wavelength, a, energy,
				System.currentTimeMillis());
	}

	public void updateChart(float wl, float abs, float trans, int energy,
			boolean isRezero) {
		SharePreferenceUtil sp = OnlabApplication.getInstance().getSpUtil();
		int testMode = sp.getWSTestMode();
		if (testMode == WSSettingActivity_.TEST_MODE_ABS) {
			if (isRezero) {
				mChart.add2(wl, abs);
			} else {
				// TODO:??
				mChart.add(lineIndex, wl, abs);
			}
		} else if (testMode == WSSettingActivity_.TEST_MODE_TRANS) {
			if (isRezero) {
				mChart.add2(wl, trans * 100);
			} else {
				// TODO:??
				mChart.add(lineIndex, wl, trans * 100);
			}
		} else if (testMode == WSSettingActivity_.TEST_MODE_ENERGY) {
			if (isRezero) {
				mChart.add2(wl, energy);
			} else {
				// TODO:??
				mChart.add(lineIndex, wl, energy);
			}
		}
		mChartView.postInvalidate();
		if (!isRezero) {
			addOneTestItem(new WavelengthScanningRecord(-1, wl, abs, trans,
					energy, System.currentTimeMillis()));
		}
	}
	
	public void wsTestDone() {
		lineIndex = lineIndex + 1;
	}

	public void systemBaseline() {
		mBaselineDialog.show();
	}

	public void baselineFinish() {
		mBaselineDialog.doFinish();
	}

	@Override
	public void onClick(View arg0) {
		// TODO Auto-generated method stub
		switch (arg0.getId()) {
		case R.id.btn_start_test:
			boolean isCreated = OnlabApplication.getInstance().getSpUtil()
					.isBaselineCreated();
			if (!isRezeroed) {
				mToastShow.toastShow(getString(R.string.notice_do_rezero));
				return;
			}
			if (isCreated) {
				clearData();
				mChart.clear2();
				mChartView.postInvalidate();
				SharePreferenceUtil sp = OnlabApplication.getInstance()
						.getSpUtil();
				float startWl = sp.getWSStartWl();
				float endWl = sp.getWSEndWl();
				float interval = sp.getWSInterval();
				((MainActivity_) getActivity()).prepareTest(startWl, endWl,
						interval);
				((MainActivity_) getActivity()).doTest(endWl, -1, -1, -1);
				((MainActivity_) getActivity()).showWavelengthReset();
			} else {
				mToastShow.toastShow(getString(R.string.notice_build_baseline));
			}
			break;
		case R.id.btn_stop_test:
			((MainActivity_) getActivity()).stopWsTest();
			break;
		case R.id.btn_rezero_test:
			// ((MainActivity_) getActivity()).rezero();
			if (isRezeroing) {
				return;
			}
			isCreated = OnlabApplication.getInstance().getSpUtil()
					.isBaselineCreated();
			if (isCreated) {
				// clearData();
				mChart.clear2();
				mChartView.postInvalidate();
				SharePreferenceUtil sp = OnlabApplication.getInstance()
						.getSpUtil();
				float startWl = sp.getWSStartWl();
				float endWl = sp.getWSEndWl();
				float interval = sp.getWSInterval();
				((MainActivity_) getActivity()).prepareTest(startWl, endWl,
						interval);
				((MainActivity_) getActivity()).doRezero(endWl, -1, -1, -1);
				((MainActivity_) getActivity()).showWavelengthReset();
				isRezeroing = true;
			} else {
				mToastShow.toastShow(getString(R.string.notice_build_baseline));
			}
			break;
		case R.id.btn_system_baseline:
			systemBaseline();
			break;

		case R.id.dialog_baseline_open:
			isCreated = OnlabApplication.getInstance().getSpUtil()
					.isBaselineCreated();
			if (isCreated) {
				int[] base = OnlabApplication.getInstance().getSpUtil()
						.getBaseline();
				mBaselineDialog.showBaseline(base);
			} else {
				mToastShow.toastShow("还没建立过系统基线，请先建立");
			}
			break;
		case R.id.dialog_baseline_save:
			((MainActivity_) getActivity()).baseline_save();
			break;
		case R.id.dialog_baseline_start:
			if (!mBaselineDialog.isRunning()) {
				mBaselineDialog.setStart();
				((MainActivity_) getActivity()).prepareBaseline(190.0f,
						1100.0f, 1.0f);
				((MainActivity_) getActivity()).doBaseline(-1);
				((MainActivity_) getActivity()).showWavelengthReset();
			} else {
				mBaselineDialog.setStop();
				((MainActivity_) getActivity()).stopBaseline();
			}
			break;
		case R.id.dialog_baseline_return:
			mBaselineDialog.dismiss();
			if (mBaselineDialog.isRunning()) {
				mBaselineDialog.setStop();
				((MainActivity_) getActivity()).stopBaseline();
			}
			break;

		case R.id.dialog_save_button:
			String name = mDialog.getEditText();
			if (name.length() < 1) {
				mToastShow.toastShow(getString(R.string.name_cannot_null));
			} else {
				// check the name is already availiable
				List<String> namesList = OnlabApplication.getInstance()
						.getWavelengthScanningDB().getTables();
				for (int i = 0; i < namesList.size(); i++) {
					if (namesList.get(i).equals(name)) {
						mToastShow
								.toastShow(getString(R.string.name_already_exist));
						return;
					}
				}

				String recordName = name;
				for (int i = 0; i < mData.size(); i++) {
					int index = 0;
					float wavelength = 0;
					float abs = 0.0f;
					float trans = 0.0f;
					int energy = 0;
					long date = 0;

					HashMap<String, String> map = mData.get(i);
					index = Integer.parseInt(map.get("id"));
					wavelength = Float.parseFloat(map.get("wavelength"));
					abs = Float.parseFloat(map.get("abs"));
					trans = Float.parseFloat(map.get("trans"));
					energy = Integer.parseInt(map.get("energy"));
					date = Long.parseLong(map.get("date"));

					WavelengthScanningRecord record = new WavelengthScanningRecord(
							index, wavelength, abs, trans, energy, date);
					OnlabApplication.getInstance().getWavelengthScanningDB()
							.saveRecord(recordName, record);
				}
				mDialog.dismiss();
			}
			break;
		case R.id.dialog_cancel_button:
			mDialog.dismiss();
			break;
		default:
			break;
		}
	}

}
